﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.IO;
using System.Threading.Tasks;
using KeanuMvc.Reference;

namespace HISRestServices {

    public class JsonNetMediaTypeFormatter : JsonMediaTypeFormatter {


        private static readonly MediaTypeHeaderValue jsonMediaType = new MediaTypeHeaderValue("application/json");
        /// <summary>
        /// Initializes a new instance of the <see cref="JsonNetMediaTypeFormatter"/> class.
        /// </summary>
        public JsonNetMediaTypeFormatter() {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" });
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json") { CharSet = "utf-8" });
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/bson"));
            this.MediaTypeMappings.Add(new QueryStringMapping("format", "json", jsonMediaType));
        }

        /// <summary>
        /// Called when [read from stream].
        /// </summary>
        /// <param name="type">The type of object to deserialize.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="httpContentHeaders">The HTTP content headers.</param>
        /// <returns>The de-serialized object.</returns>
        /// <remarks></remarks>
        protected override object OnReadFromStream(Type type, Stream stream, HttpContentHeaders httpContentHeaders) {
            if (type == null) {
                throw new ArgumentNullException("type");
            }

            if (stream == null) {
                throw new ArgumentNullException("stream");
            }

            return httpContentHeaders.ContentType.MediaType.Equals("application/bson", StringComparison.InvariantCultureIgnoreCase)
                ? stream.ReadAsBson(type)
                : stream.ReadAsJson(type);
        }

        /// <summary>
        /// Called to write an object to the <paramref name="stream"/>.
        /// </summary>
        /// <param name="type">The type of object to write.</param>
        /// <param name="value">The object instance to write.</param>
        /// <param name="stream">The <see cref="T:System.IO.Stream"/> to which to write.</param>
        /// <param name="httpContentHeaders">The HTTP content headers.</param>
        /// <param name="context">The <see cref="T:System.Net.TransportContext"/>.</param>
        /// <remarks></remarks>
        protected override void OnWriteToStream(Type type, object value, Stream stream, HttpContentHeaders httpContentHeaders, System.Net.TransportContext context) {
            if (type == null) {
                throw new ArgumentNullException("type");
            }

            if (stream == null) {
                throw new ArgumentNullException("stream");
            }

            if (httpContentHeaders.ContentType.MediaType.Equals("application/bson", StringComparison.InvariantCultureIgnoreCase)) {
                stream.WriteAsBson(value);
            } else {
                stream.WriteAsJson(value);
            }
        }
    }
}